package com.torry.edss.domain.accessor.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.torry.edss.domain.accessor.dto.FindLimitUpDTO;
import com.torry.edss.domain.valueobject.QuantityType;
import com.torry.edss.infras.entity.LimitUpDO;
import com.torry.edss.domain.model.LimitUp;
import com.torry.edss.infras.mapper.LimitUpMapper;
import com.torry.edss.domain.accessor.LimitUpAccessor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import com.torry.boot.starter.mybatisplus.service.AccessorImpl;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author torry.wang
 * @since 2025-05-09
 */
@Service
@SuppressWarnings("DuplicatedCode")
public class LimitUpAccessorImpl extends AccessorImpl<LimitUpMapper, LimitUpDO, LimitUp> implements LimitUpAccessor {

    @Resource
    private LimitUpMapper limitUpMapper;

    @Override
    public LimitUp toModel(LimitUpDO entity) {
        if (entity == null) return null;
        LimitUp limitUp = new LimitUp();
        limitUp.setDate(entity.getDate());
        limitUp.setCompanyId(entity.getCompanyId());
        limitUp.setPrice(entity.getPrice());
        limitUp.setQuantityType(entity.getQuantityType() == null ? null : QuantityType.parse(entity.getQuantityType()));
        limitUp.setUpPercentage(entity.getUpPercentage());
        limitUp.setMarketValue(entity.getMarketValue());
        limitUp.setTransactionAmount(entity.getTransactionAmount());
        limitUp.setSealAmount(entity.getSealAmount());
        limitUp.setSealTransactionPercentage(entity.getSealTransactionPercentage());
        limitUp.setTurnoverPercentage(entity.getTurnoverPercentage());
        limitUp.setLimitTime(entity.getLimitTime());
        limitUp.setLastLimitTime(entity.getLastLimitTime());
        limitUp.setBombCount(entity.getBombCount());
        limitUp.setStat(entity.getStat());
        limitUp.setContinuousCount(entity.getContinuousCount());
        limitUp.setCovered(entity.getCovered() == null ? null : entity.getCovered() == 1);
        limitUp.setInterrupted(entity.getInterrupted() == null ? null : entity.getInterrupted() == 1);
        limitUp.setPreviousLimitUpIntervalDays(entity.getPreviousLimitUpIntervalDays());
        limitUp.setLogic(entity.getLogic());
        limitUp.setTagId(entity.getTagId());
        limitUp.setQuantity(entity.getQuantity());
        limitUp.setPreviousDayQuantity(entity.getPreviousDayQuantity());
        limitUp.setId(entity.getId());
        limitUp.setCreateTime(entity.getCreateTime());
        limitUp.setUpdateTime(entity.getUpdateTime());
        return limitUp;
    }

    @Override
    public LimitUpDO toEntity(LimitUp model) {
        if (model == null) return null;
        LimitUpDO limitUpDO = new LimitUpDO();
        limitUpDO.setDate(model.getDate());
        limitUpDO.setCompanyId(model.getCompanyId());
        limitUpDO.setPrice(model.getPrice());
        limitUpDO.setQuantityType(model.getQuantityType() == null ? null : model.getQuantityType().getCode());
        limitUpDO.setUpPercentage(model.getUpPercentage());
        limitUpDO.setMarketValue(model.getMarketValue());
        limitUpDO.setTransactionAmount(model.getTransactionAmount());
        limitUpDO.setSealAmount(model.getSealAmount());
        limitUpDO.setSealTransactionPercentage(model.getSealTransactionPercentage());
        limitUpDO.setTurnoverPercentage(model.getTurnoverPercentage());
        limitUpDO.setLimitTime(model.getLimitTime());
        limitUpDO.setLastLimitTime(model.getLastLimitTime());
        limitUpDO.setBombCount(model.getBombCount());
        limitUpDO.setStat(model.getStat());
        limitUpDO.setContinuousCount(model.getContinuousCount());
        limitUpDO.setCovered(model.getCovered() == null ? null : model.getCovered() ? 1 : 0);
        limitUpDO.setInterrupted(model.getInterrupted() == null ? null : model.getInterrupted() ? 1 : 0);
        limitUpDO.setPreviousLimitUpIntervalDays(model.getPreviousLimitUpIntervalDays());
        limitUpDO.setLogic(model.getLogic());
        limitUpDO.setTagId(model.getTagId());
        limitUpDO.setId(model.getId());
        limitUpDO.setQuantity(model.getQuantity());
        limitUpDO.setPreviousDayQuantity(model.getPreviousDayQuantity());
        limitUpDO.setCreateTime(model.getCreateTime());
        limitUpDO.setUpdateTime(model.getUpdateTime());
        return limitUpDO;
    }

    @Override
    public int countByDate(String date) {
        return this.count(new LambdaQueryWrapper<LimitUpDO>().eq(LimitUpDO::getDate, date));
    }

    @Override
    public int countByDateAndCompanyId(List<String> dates, Long companyId) {
        return this.count(new LambdaQueryWrapper<LimitUpDO>().in(LimitUpDO::getDate, dates).eq(LimitUpDO::getCompanyId, companyId));
    }

    @Override
    public List<LimitUp> findByDate(String date) {
        return this.list(new LambdaQueryWrapper<LimitUpDO>().eq(LimitUpDO::getDate, date));
    }

    @Override
    public List<LimitUp> findByDateAndContinuousCount(List<String> dates, List<Integer> continuousCounts, Double volumeMultiple) {
        if (CollectionUtils.isEmpty(dates) || CollectionUtils.isEmpty(continuousCounts)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<LimitUpDO> wrapper = new LambdaQueryWrapper<LimitUpDO>()
                .in(LimitUpDO::getDate, dates)
                .in(LimitUpDO::getContinuousCount, continuousCounts);
        if (volumeMultiple != null) {
            wrapper.apply("quantity / previous_day_quantity < " + volumeMultiple);
        }
        return this.list(wrapper);
    }

    @Override
    public List<LimitUp> findLimitUps(FindLimitUpDTO dto) {
        List<LimitUpDO> limitUps = limitUpMapper.selectLimitUps(dto);
        return limitUps.stream().map(this::toModel).collect(Collectors.toList());
    }
}
